#include "../../../shared/dal/chat_session_dao.hpp"
#include "../../../shared/dal/user_relation_dao.hpp"
#include "../../../shared/dal/friend_apply_dao.hpp"
#include "../../../shared/dal/odb_factory.hpp"
#include "../../../entity/user_relation.hxx"
#include "../../../entity/friend_apply.hxx"
#include "../../../entity/chat_session.hxx"
#include "user_relation-odb.hxx"
#include "chat_session-odb.hxx"
#include "friend_apply-odb.hxx"
#include "logger.hpp"
#include <boost/date_time/posix_time/ptime.hpp>
#include <gflags/gflags.h>
#include <iostream>
#include <memory>
#include <string>
#include <gtest/gtest.h>
#include <vector>

shared::dal::ChatSessionDaoPtr chatSessionDao;
shared::dal::UserRelationDaoPtr userRelationDao;
shared::dal::FriendApplyDaoPtr friendApplyDao;

// TEST(UserRelationDBTest, DataAccess)
// {
//     std::vector<std::string> userIdList = {"uid2", "uid3", "uid4"};
//     for(auto& uid : userIdList) {
//         userRelationDao->insert("uid1", uid);
//     }
//     auto res = userRelationDao->selectFriends("uid1");
//     ASSERT_EQ(res.size(), userIdList.size());
//     for(int i = 0; i < res.size(); ++i) {
//         ASSERT_EQ(userIdList[i], res[i]);
//     }

//     std::string removeUserId = "uid3";
//     userRelationDao->remove("uid1", removeUserId);
//     ASSERT_FALSE(userRelationDao->exists("uid1", removeUserId));
// }

TEST(FriendApplyDBTest, DataAccess)
{
    std::vector<entity::FriendApply> friendApplyList {
        {"111", "uid1", "uid2"},
        {"222", "uid1", "uid3"},
        {"333", "uid4", "uid3"}
    };
    for(auto& fa : friendApplyList) {
        friendApplyDao->insert(fa);
    }
    auto res = friendApplyDao->selectFriendApply("uid3");   // 获取uid3用户的请求列表
    ASSERT_EQ(res.size(), 2);
    for(int i = 0; i < res.size(); ++i) {
        ASSERT_EQ(friendApplyList[i + 1].requesterId(), res[i]);
    }

    ASSERT_TRUE(friendApplyDao->selectFriendApply("uid4").empty());
    ASSERT_TRUE(friendApplyDao->selectFriendApply("uid1").empty());

    friendApplyDao->remove("uid1", "uid2");                         // 删除向uid2的好友申请
    ASSERT_TRUE(friendApplyDao->selectFriendApply("uid2").empty());     // 那么在uid2用户的视角, 没有人添加它好友
    ASSERT_FALSE(friendApplyDao->exists("uid1", "uid2"));     
}

TEST(ChatSessionDBTest, DataAccess)
{
    std::vector<entity::ChatSession> chatSessionList {
        {"session-1", "session-1-name", 1},
        {"session-2", "session-2-name", 1},
        {"session-3", "session-3-name", 2}
    };
    for(auto& cs : chatSessionList) {
        chatSessionDao->insert(cs);
    }
    auto res = chatSessionDao->selectOneSession("session-1");
    ASSERT_EQ(chatSessionList[0].sessionId(), res->sessionId());
    ASSERT_EQ(chatSessionList[0].sessionName(), res->sessionName());
    ASSERT_EQ(chatSessionList[0].sessionType(), res->sessionType());

    auto res2 = chatSessionDao->selectAllSingleSession("uid1");
    ASSERT_EQ(res2.size(), 2);
    for(auto& info : res2) {
        std::cout << info.chatSessionId << '\n';
        std::cout << info.friendId << '\n';
    }

    auto res3 = chatSessionDao->selectAllGroupSession("uid2");
    ASSERT_EQ(res3.size(), 1);
    for(auto& info : res3) {
        std::cout << info.chatSessionId << '\n';
        std::cout << info.chatSessionName << '\n';
    }

    chatSessionDao->remove("session-2");
    res = chatSessionDao->selectOneSession("session-2");
    ASSERT_FALSE(res);

    chatSessionDao->remove("uid1", "uid2");  // 删除指定二者相关的单聊会话
    res = chatSessionDao->selectOneSession("session-1");
    ASSERT_FALSE(res);
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);

    auto db = shared::dal::ODBFactory::create("root", "weng9244", "127.0.0.1", "chat_system", "utf8", 0, 1);
    
    chatSessionDao = std::make_shared<shared::dal::ChatSessionDao>(db);
    userRelationDao = std::make_shared<shared::dal::UserRelationDao>(db);
    friendApplyDao = std::make_shared<shared::dal::FriendApplyDao>(db);

    return RUN_ALL_TESTS();
}